// 预处理的应用
// Created by Administrator on 2025/6/16.
// 概述：
// 编辑器在实际预编译之前所需要完成的预处理
// 注意：定义宏时结尾不能带分号 ( ; )


#include <iostream> // #include 这个宏用于引入头文件
using namespace std;

/**
 * 创建一个常量，该常量名称（SIZE）称之为 “ 宏 ”，该宏名所代表的值为100
 */
#define SIZE 100

void print() {
    cout << "value of size：" << SIZE;
    // 编辑前该语句会替换为： cout << "value of size：" << 100
}

/**
 * 创建一个带有参数的宏
 * @param a 参数A
 * @param b 参数B
 */
#define MIN( a , b ) (a > b ? b : a )

void minFunc() {
    int minValue = MIN(10, 20);
    cout << "最小值为：" << minValue << endl;
}

/**
 * 声明一个宏
 * 该宏没有值，后续使用 #ifdef 判断该宏是否被定义
 */
#define DEBUG

void func() {
    int i = 100, j = 200;

#ifdef DEBUG // 判断 "DEBUG" 这个宏是否被定义，如果被定义则执行下面的代码，否则不执行（你可以把上面的宏（DEBUG）给注释掉，方便理解）
    cout << "debug main function" << endl; // 条件为true 这段代码会被编译并执行，否则会被忽略掉不参与编译
#endif

#if 0 // 0 = false，下面这段代码语法明显是错误的，但是由于条件为false不会参与编译（IDE也不会进行语法识别），所以不会报错
    cout << MKSTR(HELLO C++) << endl;
#endif
    // 打印最小值
    cout << "The minimum is :" << MIN(i, j) << endl;

#ifdef DEBUG
    cerr << "Trace Coming out of main function" << endl;
#endif
}

/**
 * #if 和 #ifdef 有什么区别？
 *
 * if：判断宏的结果值是否为true，如果为true则执行。声明了一个宏没有给默认值，那么这个宏默认为false
 * ifdef：判断宏是否被定义，如果被定义则执行。
 */


/**
 * # 和 ## 运算符
 *
 *
 */

#define MKSTR(x) #x // # 运算符，将参数 x 转换为字符串，如： hello -> "hello"

void func2() {
    // string name = "你好";
    // cout << MKSTR(name) << endl; // 错误的使用方法，最终输出的是“name”而不是“你好”，因为 MKSTR 是预处理时的在程序编译前就存在了所以获取不到name信息

    cout << MKSTR(你好) << endl;
    // cout << "你好" << endl; // 运行时换成此行代码
}

#define CONCAT( x , y ) x ## y // ## 运算符，将参数 x 和参数 y 连接起来，如： hello 和 world -> helloworld。注意：只能用于变量名或函数名拼接

void func3() {
    int xy = 100;
    cout << CONCAT(x, y) << endl; // 注意这里的 x 和 y 是两个字符并非变量名
    // 将 x 和 y 两个字符拼接在一起了，也就是 xy ，由于上面已经定义了 xy 变量，所以这里变成了打印输出
    // 编译时的代码为：cout << xy << endl;

    // cout<< CONCAT("你好","world") << endl; // 错误：不能用于字符串或者数字拼接，只能用于变量名或函数名
}

/**
 *  C++中的一些预定义的宏
 */
void builtInMacroFunc() {
    cout << "当前行号:\t" << __LINE__ << endl;
    cout << "当前文件名:\t" << __FILE__ << endl;
    cout << "编译日期:\t" << __DATE__ << endl;
    cout << "编译时间:\t" << __TIME__ << endl;
}

#define NUM 10

void func4() {
#if NUM > 5
    cout << "NUM > 5" << endl;
#else
    cout << "NUM < 5" << endl;
#endif


}

int main(int argc, char *argv[]) {
    // minFunc();
    // func();
    // func2();
    // func3();
    builtInMacroFunc();
}
